Package weasel.compiler.v2

Source Code of weasel.compiler.v2.WeaselMethodBodyCompilerV2

package weasel.compiler.v2;

import java.util.List;
import java.util.ListIterator;

import weasel.compiler.WeaselBlockInfo;
import weasel.compiler.WeaselClassCompiler;
import weasel.compiler.WeaselCompiler;
import weasel.compiler.WeaselCompilerException;
import weasel.compiler.WeaselCompilerMessage;
import weasel.compiler.WeaselCompilerMessage.MessageType;
import weasel.compiler.WeaselInstructionList;
import weasel.compiler.WeaselKeyWordCompilerHelper;
import weasel.compiler.WeaselToken;
import weasel.compiler.WeaselTokenType;
import weasel.compiler.WeaselVariableInfo;
import weasel.compiler.keywords.WeaselKeyWord;
import weasel.compiler.v2.tokentree.WeaselParameterCompileReturn;
import weasel.compiler.v2.tokentree.WeaselTree;
import weasel.interpreter.WeaselGenericClass;
import weasel.interpreter.WeaselGenericField;
import weasel.interpreter.WeaselGenericMethod;
import weasel.interpreter.WeaselGenericMethod2;
import weasel.interpreter.WeaselMethod;
import weasel.interpreter.WeaselMethodBody;
import weasel.interpreter.WeaselModifier;
import weasel.interpreter.bytecode.WeaselInstruction;
import weasel.interpreter.bytecode.WeaselInstructionInvoke;
import weasel.interpreter.bytecode.WeaselInstructionJump;
import weasel.interpreter.bytecode.WeaselInstructionLoadVariable;
import weasel.interpreter.bytecode.WeaselInstructionPop;
import weasel.interpreter.bytecode.WeaselInstructionPops;
import weasel.interpreter.bytecode.WeaselInstructionReturn;

public class WeaselMethodBodyCompilerV2 extends WeaselMethodBody implements WeaselKeyWordCompilerHelper {

  protected final WeaselCompiler compiler;
  protected final WeaselClassCompilerV2 classCompiler;
  protected final List<WeaselToken> methodTokens;
  protected int methodTokenPos;
  protected final List<String> paramNames;
  protected final List<Integer> paramModifier;
  protected WeaselGenericMethod2 wgm;
  protected WeaselBlockInfo block;
  protected boolean superCaller;
 
  protected WeaselMethodBodyCompilerV2(WeaselMethod method, WeaselClassCompilerV2 classCompiler, List<WeaselToken> methodTokens, List<String> paramNames, List<Integer> paramModifier, WeaselCompiler compiler) {
    super(method, classCompiler);
    this.compiler = compiler;
    this.classCompiler = classCompiler;
    instructions = new WeaselInstruction[0];
    this.methodTokens = methodTokens;
    this.paramNames = paramNames;
    this.paramModifier = paramModifier;
  }

  protected WeaselMethodBodyCompilerV2(WeaselMethod method, WeaselClassCompilerV2 classCompiler) {
    super(method, classCompiler);
    this.classCompiler = classCompiler;
    compiler = null;
    methodTokens = null;
    paramNames = null;
    paramModifier = null;
  }

  public void compile() {
    wgm = new WeaselGenericMethod(classCompiler.genericClass, method).getMethod(new WeaselGenericClass[0]);
    if(isNative()){
      return;
    }
    System.out.println(method+":"+methodTokens);
    if(WeaselModifier.isStatic(method.getModifier())){
      block = new WeaselBlockInfo(false, -paramNames.size() + 1);
    }else{
      block = new WeaselBlockInfo(false, -paramNames.size());
      block.newVar(0, "this", classCompiler.genericClass);
    }
    for(int i=0; i<paramNames.size(); i++){
      WeaselGenericMethod2 genericMethod = classCompiler.genericClass.getGenericMethod(method.getNameAndDesk(), null);
      block.newVar(paramModifier.get(i), paramNames.get(i), genericMethod.getGenericParams()[i]);
    }
    WeaselInstructionList instructions = new WeaselInstructionList();
    ListIterator<WeaselToken> iterator = methodTokens.listIterator();
    if(method.getName().equals("<preInit>")){
      if(method.getParentClass().getSuperClass()!=null){
        instructions.add(0, new WeaselInstructionLoadVariable(getVariable("this").pos));
        instructions.add(0, new WeaselInstructionInvoke(method.getParentClass().getSuperClass().getRealName()+".<preInit>()"));
      }
    }else if(method.getName().equals("<init>")){
      boolean auto = true;
      if(iterator.hasNext()){
        WeaselToken token = iterator.next();
        if(token!=null && token.tokenType==WeaselTokenType.KEYWORD){
          if(iterator.next().tokenType==WeaselTokenType.OPENBRACKET){
            try{
              if(token.param==WeaselKeyWord.THIS){
                superCaller = false;
                auto = false;
                WeaselTree tree = WeaselTree.parse(iterator, WeaselTokenType.CLOSEBRACKET);
                List<WeaselGenericMethod2> methods = classCompiler.genericClass.getGenericMethodsOfThis("<init>", true);
                WeaselParameterCompileReturn wpcr = WeaselTree.compileParamList(token.line, "<init>", compiler, this, tree, methods);
                instructions.addAll(wpcr.instructions);
                instructions.add(token.line, new WeaselInstructionInvoke(wpcr.method.getMethod().getMethod().getClassNameAndDesk()));
                token = iterator.next();
                if(token.tokenType!=WeaselTokenType.SEMICOLON)
                  throw new WeaselCompilerException(token.line, "Expect ; but got %s", token);
              }else if(token.param==WeaselKeyWord.SUPER){
                superCaller = true;
                auto = false;
                WeaselTree tree = WeaselTree.parse(iterator, WeaselTokenType.CLOSEBRACKET);
                List<WeaselGenericMethod2> methods = classCompiler.genericClass.getGenericSuperClass().getGenericMethodsOfThis("<init>", true);
                WeaselParameterCompileReturn wpcr = WeaselTree.compileParamList(token.line, "<init>", compiler, this, tree, methods);
                instructions.addAll(wpcr.instructions);
                instructions.add(token.line, new WeaselInstructionInvoke(wpcr.method.getMethod().getMethod().getClassNameAndDesk()));
                token = iterator.next();
                if(token.tokenType!=WeaselTokenType.SEMICOLON)
                  throw new WeaselCompilerException(token.line, "Expect ; but got %s", token);
              }else{
                iterator.previous();
                iterator.previous();
              }
            }catch(WeaselCompilerException e){
              compiler.addWeaselCompilerMessage(new WeaselCompilerMessage(MessageType.ERROR, e.getLine(), parentClass.getFileName(), e.getMessage()));
              iterator.previous();
              token = iterator.next();
              while(token.tokenType!=WeaselTokenType.SEMICOLON && iterator.hasNext()){
                token = iterator.next();
              }
            }
          }else{
            iterator.previous();
            iterator.previous();
          }
        }else{
          iterator.previous();
        }
      }
      if(auto){
        superCaller = true;
        if(classCompiler.genericClass.getGenericSuperClass()!=null){
          WeaselGenericMethod2 method = classCompiler.genericClass.getGenericSuperClass().getGenericMethodOfThis("<init>()", new WeaselGenericClass[0]);
          if(method==null){
            compiler.addWeaselCompilerMessage(
                new WeaselCompilerMessage(MessageType.ERROR, 0, parentClass.getFileName(),
                    String.format("No default constructor in %s found", classCompiler.genericClass.getGenericSuperClass())));
          }else{
            instructions.add(0, new WeaselInstructionInvoke(method.getMethod().getMethod().getClassNameAndDesk()));
          }
        }
      }
    }
    while(iterator.hasNext()){
      try{
        instructions.addAll(WeaselTree.parseAndCompile(compiler, this, iterator));
      }catch(WeaselCompilerException e){
        compiler.addWeaselCompilerMessage(new WeaselCompilerMessage(MessageType.ERROR, e.getLine(), parentClass.getFileName(), e.getMessage()));
        iterator.previous();
        WeaselToken token = iterator.next();
        while(token.tokenType!=WeaselTokenType.SEMICOLON && iterator.hasNext()){
          token = iterator.next();
        }
      }
    }
    instructions.add(0, new WeaselInstructionReturn(block.varsToPop()));
    System.out.println(instructions);
    this.instructions = instructions.getInstructions();
  }
 
  @Override
  public WeaselVariableInfo getVariable(String name) {
    return block.getVar(name);
  }

  @Override
  public List<WeaselGenericMethod2> getGenericMethods(String name) throws WeaselCompilerException {
    return classCompiler.genericClass.getGenericMethods(name, !WeaselModifier.isStatic(method.getModifier()));
  }

  @Override
  public WeaselGenericField getGenericField(String variable) {
    return classCompiler.genericClass.getGenericField(variable);
  }

  @Override
  public WeaselGenericMethod2 getCompilingMethod() {
    return wgm;
  }

  @Override
  public WeaselClassCompiler getClassCompiler() {
    return classCompiler;
  }

  @Override
  public WeaselVariableInfo newVar(int modifier, String varName, WeaselGenericClass wgc) {
    return block.newVar(modifier, varName, wgc);
  }

  @Override
  public void writeVar(WeaselVariableInfo wvi) {
   
  }

  @Override
  public void openBlock(boolean canAddBreaks) {
    block = new WeaselBlockInfo(canAddBreaks, block);
  }

  @Override
  public WeaselBlockInfo closeBlock() {
    WeaselBlockInfo b = block;
    block = block.base;
    return b;
  }

  @Override
  public int getVarCount() {
    WeaselBlockInfo b = block;
    int count = 0;
    while(b!=null){
      count += b.varsToPop();
      b = b.base;
    }
    return count;
  }

  @Override
  public void addBreak(int s, WeaselInstructionJump breakJump) {
    WeaselBlockInfo b = block;
    while(s>1){
      if(b.canAddBreaks){
        s--;
      }
      b = b.base;
    }
    while(!b.canAddBreaks){
      b = b.base;
    }
    b.breaks.add(breakJump);
  }
 
  @Override
  public void addContinue(int s, WeaselInstructionJump continueJump) {
    WeaselBlockInfo b = block;
    while(s>1){
      if(b.canAddBreaks){
        s--;
      }
      b = b.base;
    }
    while(!b.canAddBreaks){
      b = b.base;
    }
    b.continues.add(continueJump);
  }

  @Override
  public void addClosingsAndFrees(int s, WeaselInstructionList instructionList, boolean last) {
    int frees = 0;
    WeaselBlockInfo b = block;
    while(s>1){
      if(b.canAddBreaks){
        s--;
      }
      frees += b.variables.size();
      if(b.exiting!=null)
        instructionList.addWithoutLine(b.exiting.create());
      b = b.base;
    }
    while(!b.canAddBreaks){
      frees += b.variables.size();
      if(b.exiting!=null)
        instructionList.addWithoutLine(b.exiting.create());
      b = b.base;
    }
    if(last){
      frees += b.variables.size();
    }
    if(b.exiting!=null)
      instructionList.addWithoutLine(b.exiting.create());
    if(frees==1)
      instructionList.addWithoutLine(new WeaselInstructionPop());
    else if(frees>1)
      instructionList.addWithoutLine(new WeaselInstructionPops(frees));
  }
 
}
TOP

Related Classes of weasel.compiler.v2.WeaselMethodBodyCompilerV2

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.